package tankgame06;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.util.List;
import java.util.Vector;

/**
 * @author 谷其昊
 * @version 1.0
 * @date 2022/2/12
 * @time 18:57
 */
@SuppressWarnings("all")
public class MyPanel extends JPanel implements KeyListener ,Runnable {
    private Hero hero;

    private List<Node> nodes = new Vector<>();

    /**
     * 有多线程
     * 使用Vector比ArrayList更合适
     */
    private List<EnemyTank> enemyTanks = new Vector<>();
    private int enemyTanksSize = 3;

    //存放炸弹
    Vector<Bomb> bombs =  new Vector<Bomb>();

    //定义三张炸弹图片，用于显示爆炸效果
    Image image1 = null;
    Image image2 = null;
    Image image3 = null;

    public MyPanel(String key) {

        //判断记录文件是否存在
        //存在就正常执行，不存在就提示并将key置为1
        File file = new File(Recorder.getRecordFile());
        if (file.exists()){
            nodes = Recorder.getNodeAndEnemyTankNum();
        }else{
            System.out.println("文件不存在，只能开启新的游戏");
            key = "1";
        }


        //初始化自己坦克
        if (hero == null)
            this.hero = new Hero(400, 500);
        Recorder.setEnemyTanks(enemyTanks);

        switch (key){
            case "1":{
                //开启新游戏
                //初始化敌人坦克
                for (int i = 0; i < enemyTanksSize; i++) {
                    EnemyTank enemyTank = new EnemyTank(100 * (i + 1), 100);
                    enemyTank.setSpeed(2);
                    enemyTank.setDirection(2);
                    new Thread(enemyTank).start();
                    //给敌人坦克加入子弹
                    Bullet bullet = new Bullet(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirection());
                    enemyTank.bullets.add(bullet);
                    new Thread(bullet).start();
                    enemyTanks.add(enemyTank);
                    enemyTank.setEnemyTanks(enemyTanks);
                }
                this.hero.setSpeed(5);
            }
            break;
            case "2":{
                //继续上局游戏
                //初始化敌人坦克
                for (int i = 0; i < nodes.size(); i++) {
                    Node node = nodes.get(i);
                    EnemyTank enemyTank = new EnemyTank(node.getX(), node.getY());
                    enemyTank.setSpeed(2);
                    enemyTank.setDirection(node.getDirection());
                    new Thread(enemyTank).start();
                    //给敌人坦克加入子弹
                    Bullet bullet = new Bullet(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirection());
                    enemyTank.bullets.add(bullet);
                    new Thread(bullet).start();
                    enemyTanks.add(enemyTank);
                    enemyTank.setEnemyTanks(enemyTanks);
                }
                this.hero.setSpeed(5);
            }
            break;
            default:
                System.out.println("你的输入有误");
                System.exit(0);
        }


        //初始化图片
        image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_1.gif"));
        image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_2.gif"));
        image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_3.gif"));

        //在这里播放指定的音乐
        new AePlayWave("src\\111.wav").start();

    }

    /**
     * 显示我方击毁敌方坦克的信息
     * @param g 画笔
     */
    public void showInfo(Graphics g){
        g.setColor(Color.BLACK);
        Font font = new Font("宋体", Font.BOLD, 25);
        g.setFont(font);
        g.drawString("您累计击毁敌方坦克",1020,30);
        drawTank(1020,60,g,0,0);
        g.setColor(Color.black);
        g.drawString(Recorder.getAllEnemyTankNum()+"",1080,100);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        showInfo(g);
        //绘制游戏区域
        g.fillRect(0, 0, 1000, 750);
        //绘制我方坦克
        if (hero.isAlive && hero != null ){
            drawTank(hero.getX(), hero.getY(), g, hero.getDirection(), hero.getType());
        }
        //画出自己的子弹，有子弹并且子弹状态存活时
//        if (hero.bullet != null && hero.bullet.isAlive == true){
//            g.draw3DRect(hero.bullet.x,hero.bullet.y,1,1,false);
//        }
        for (int i = 0; i < hero.bullets.size(); i++) {
            Bullet bullet = hero.bullets.get(i);
            if (bullet != null && bullet.isAlive){
                  g.draw3DRect(bullet.x,bullet.y,1,1,false);
            }else{
                hero.bullets.remove(bullet);
            }
        }

        //如果bombs不为空，则绘制炸弹
        for (int i = 0; i < bombs.size(); i++) {
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //取出炸弹
            Bomb bomb = bombs.get(i);
            //根据当前这个bomb对象的life值区画出相应的图片
            if (bomb.life > 6){
                g.drawImage(image1,bomb.x,bomb.y,60,60,this);
            }else if (bomb.life > 3){
                g.drawImage(image2,bomb.x,bomb.y,60,60,this);
            }else {
                g.drawImage(image3,bomb.x,bomb.y,60,60,this);
            }
            //让炸弹的生命值减少
            bomb.lifeDown();
            //如果bomb的life为0，就从bombs的集合中删除
            if (bomb.life == 0){
                bombs.remove(bomb);
            }
        }

        //绘制敌方坦克和敌方坦克子弹
        for (int i = 0; i < enemyTanks.size(); i++) {
            EnemyTank enemyTank = enemyTanks.get(i);
            //当敌人坦克存活时才绘制
            if (enemyTank.isAlive){
                drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirection(), enemyTank.getType());
                for (int i1 = 0; i1 < enemyTank.bullets.size(); i1++) {

                    //取出子弹并绘制
                    Bullet bullet = enemyTank.bullets.get(i1);
                    if (bullet.isAlive == true){
                        g.draw3DRect(bullet.x,bullet.y,1,1,false);
                    }else{
                        //移除 isAlive == false 的子弹
                        enemyTank.bullets.remove(bullet);
                    }

                }
            }
        }
    }


    /**
     * @param x         坦克的左上角x坐标
     * @param y         坦克的左上角y坐标
     * @param g         画笔
     * @param direction 坦克方向（上下左右）
     * @param type      坦克类型
     */
    public void drawTank(int x, int y, Graphics g, int direction, int type) {
        switch (type) {
            case 0:
                //敌方的坦克
                g.setColor(Color.cyan);
                break;
            case 1:
                //自己的坦克
                g.setColor(Color.yellow);
                break;
        }

        /**
         * 根据坦克方向绘制不同的性状
         * 0    上
         * 1    右
         * 2    下
         * 3    左
         *
         * 向右转之后，坦克最左上角的点
         * 与坦克向上时的最左上角的点是一个点
         *
         * 向下相对于向上，只用换下炮筒
         *
         * 左相对于右也是换个炮筒
         */
        switch (direction) {
            //向上
            case 0:
                //左轮
                g.fill3DRect(x, y, 10, 60, false);
                //右轮
                g.fill3DRect(x + 30, y, 10, 60, false);
                //中间
                g.fill3DRect(x + 10, y + 10, 20, 40, false);
                //圆
                g.fillOval(x + 10, y + 20, 20, 20);
                g.drawLine(x + 20, y, x + 20, y + 30);
                break;
            case 1:
                //上轮
                g.fill3DRect(x, y, 60, 10, false);
                //下轮
                g.fill3DRect(x, y + 30, 60, 10, false);
                //中间盖子
                g.fill3DRect(x + 10, y + 10, 40, 20, false);
                //圆
                g.fillOval(x + 20, y + 10, 20, 20);
                g.drawLine(x + 60, y + 20, x + 30, y + 20);
                break;
            case 2:
                //左轮
                g.fill3DRect(x, y, 10, 60, false);
                //右轮
                g.fill3DRect(x + 30, y, 10, 60, false);
                //中间
                g.fill3DRect(x + 10, y + 10, 20, 40, false);
                //圆
                g.fillOval(x + 10, y + 20, 20, 20);
                g.drawLine(x + 20, y + 60, x + 20, y + 30);
                break;
            case 3:
                //上轮
                g.fill3DRect(x, y, 60, 10, false);
                //下轮
                g.fill3DRect(x, y + 30, 60, 10, false);
                //中间盖子
                g.fill3DRect(x + 10, y + 10, 40, 20, false);
                //圆
                g.fillOval(x + 20, y + 10, 20, 20);
                g.drawLine(x, y + 20, x + 30, y + 20);
                break;
            default:
                System.out.println("暂时没有处理");
        }
    }

    /**
     * 敌人坦克移动
     */
    public void enemyTankMove(EnemyTank enemyTank){

            //0 1 2 3 上 右 下 左
            int direction = (int) Math.random()*4;
            switch (direction){

                case 0:
                    enemyTank.setDirection(direction);
                    int y = enemyTank.getY();
                    enemyTank.setY(y--);
                    break;
                case 1:
                    enemyTank.setDirection(direction);
                    int x = enemyTank.getX();
                    enemyTank.setX(x++);
                    break;
                case 2:
                    enemyTank.setDirection(direction);
                    int y1 = enemyTank.getY();
                    enemyTank.setY(y1++);
                    break;
                case 3:
                    enemyTank.setDirection(direction);
                    int x1 = enemyTank.getX();
                    enemyTank.setX(x1--);
                    break;
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    /**
     * 键盘被按下时调用此方法
     *
     * @param e
     */
    @Override
    public void keyPressed(KeyEvent e) {
        if (hero.isAlive) {
            if (e.getKeyCode() == KeyEvent.VK_W) {
                //改变坦克方向
                hero.setDirection(0);
                hero.moveUp();
            } else if (e.getKeyCode() == KeyEvent.VK_S) {
                hero.setDirection(2);
                hero.moveDown();
            } else if (e.getKeyCode() == KeyEvent.VK_A) {
                hero.setDirection(3);
                hero.moveLeft();
            } else if (e.getKeyCode() == KeyEvent.VK_D) {
                hero.setDirection(1);
                hero.moveRight();
            } else if (e.getKeyCode() == KeyEvent.VK_J) {
                //发射一颗子弹的情况
//            if (hero.bullet == null || !hero.bullet.isAlive){
//                hero.shootEnemyTank();
//            }

                hero.shootEnemyTank();
            }
            this.repaint();
        }
    }

    /**
     * 敌方子弹击中我方
     * @param bullets 地方子弹夹
     * @param hero    我方坦克
     */
    public void hitMyHero(List<Bullet> bullets, Hero hero){
        switch (hero.getDirection()){
            //上下
            case 0:
            case 2:
                for (Bullet bullet : bullets) {
                    if (bullet.x > hero.getX() && bullet.x < hero.getX() + 40
                            && bullet.y > hero.getY() && bullet.y < hero.getY()+60){
                        bullet.isAlive = false;
                        hero.isAlive = false;
//                        enemyTanks.remove(hero);
                        //创建Bomb对象并加入到bombs集合
                        Bomb bomb = new Bomb(hero.getX(), hero.getY());
                        bombs.add(bomb);
                    }
                }
                break;
            //左右
            case 1:
            case 3:
                for (Bullet bullet : bullets) {
                    if (bullet.x > hero.getX() && bullet.x < hero.getX() + 60
                            && bullet.y > hero.getY() && bullet.y < hero.getY()+40){
                        bullet.isAlive = false;
                        hero.isAlive = false;
//                        enemyTanks.remove(hero);
                        //创建Bomb对象并加入到bombs集合
                        Bomb bomb = new Bomb(hero.getX(), hero.getY());
                        bombs.add(bomb);
                    }
                }
                break;
        }
    }

    /**
     * 判断我方子弹是否击中敌人坦克
     * 这里使用case穿透
     * @param bullet      我方子弹
     * @param enemyTank   敌人坦克
     */
    public void  hitTank(Vector<Bullet> bullets , EnemyTank enemyTank){
        switch (enemyTank.getDirection()){
            //上下
            case 0:
            case 2:
                for (Bullet bullet : bullets) {
                    if (bullet.x > enemyTank.getX() && bullet.x < enemyTank.getX() + 40
                            && bullet.y > enemyTank.getY() && bullet.y < enemyTank.getY()+60){
                        bullet.isAlive = false;
                        enemyTank.isAlive = false;
                        enemyTanks.remove(enemyTank);
                        Recorder.addAllEnemyTankNum();
                        //创建Bomb对象并加入到bombs集合
                        Bomb bomb = new Bomb(enemyTank.getX(), enemyTank.getY());
                        bombs.add(bomb);
                    }
                }
                break;
            //左右
            case 1:
            case 3:
                for (Bullet bullet : bullets) {
                    if (bullet.x > enemyTank.getX() && bullet.x < enemyTank.getX() + 60
                            && bullet.y > enemyTank.getY() && bullet.y < enemyTank.getY()+40){
                        bullet.isAlive = false;
                        enemyTank.isAlive = false;
                        enemyTanks.remove(enemyTank);
                        Recorder.addAllEnemyTankNum();
                        //创建Bomb对象并加入到bombs集合
                        Bomb bomb = new Bomb(enemyTank.getX(), enemyTank.getY());
                        bombs.add(bomb);
                    }
                }
                break;
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //判断是否击中了敌人坦克
            //如果我的子弹还存活遍历敌人所有坦克
            if ( hero.bullet != null && hero.bullet.isAlive){

                for (int i = 0; i < enemyTanks.size(); i++) {
                    EnemyTank enemyTank = enemyTanks.get(i);
                    hitTank(hero.bullets,enemyTank);
                }

            }


                if (hero.isAlive){
                    for (int i = 0; i < enemyTanks.size(); i++) {
                        EnemyTank enemyTank = enemyTanks.get(i);
                        for (Bullet bullet : enemyTank.bullets) {
                            if (bullet != null && bullet.isAlive){
                                hitMyHero(enemyTank.bullets,hero);
                            }
                        }
                    }
                }


            this.repaint();
        }
    }
}
